#include <iostream>
#include <unistd.h>
#include <pthread.h>

#define NUM 5

using namespace std ;

int cnt = 0; 


pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER ;  //定义并初始化互斥锁

pthread_cond_t cond = PTHREAD_COND_INITIALIZER;//初始化条件变量


void * Count (void *args)
{

        pthread_detach(pthread_self()) ;
          uint64_t number= (uint64_t)args;

            std::cout << "pthread: " << number << " create success" << std::endl;
     while(true)
    {
       
        //cout << "pthread: "<<pthread_self()<< "pthread: " << number<< endl;
    
        pthread_mutex_lock (&mutex);//加锁
        pthread_cond_wait(&cond ,&mutex) ;//pthread_cond_wait让线程等待的时候，会自动释放锁
   cout << "pthread: " << number << " ， cnt: " << cnt++ << endl;
           pthread_mutex_unlock (&mutex);//解锁
    }


}


// void *getTicket(void *args)
// {
//     threadData *td = static_cast<threadData *>(args);
//     const char *name = td->threadname.c_str();
//     while (true)
//     {
//         // 线程对于锁的竞争能力可能会不同 --- 一会由例子
//         // pthread_mutex_lock(td->lock); // 申请锁成功，才能往后执行，不成功，阻塞等待。
//         pthread_mutex_lock(&lock); // 申请锁成功，才能往后执行，不成功，阻塞等待。
//         if(tickets > 0)
//         {
//             usleep(1000);
//             printf("who=%s, get a ticket: %d\n", name, tickets); // ?
//             tickets--;
//             pthread_mutex_unlock(td->lock);
//             // pthread_mutex_unlock(&lock);
//         }
//         else{
//             pthread_mutex_unlock(td->lock);
//             // pthread_mutex_unlock(&lock);
//             // wait
//         }
//         usleep(13); // 我们抢到了票，我们会立马抢下一张吗？其实多线程还要执行得到票之后的后续动作。usleep模拟
//     }
//     printf("%s ... quit\n", name);
//     return nullptr;
// }


int main()
{

for(uint64_t i = 0 ; i < NUM ; i++)  
{
      pthread_t tid ;
      // uint64_t是unsigned long int  ，在64位下是8个字节， void* 在64位下也是8字节，这样(void *)i就不会出现告警
      //必须是(void *)i ，不能是(void *)&i，如果是(void *)&i，主线程和新线程就会访问同一个i ，不方便多线程的观察
      //(void *)i ，传参是拷贝式的传参 ，这样主线程和新线程就不会共用同一个i ，不会互相影响，以便后续观察主线程和新线程


   
    pthread_create(&tid , nullptr , Count , (void *)  i ) ;   
    usleep(1000); 
}
 sleep(3);  //让新线程执行完对应的代码
    std::cout << "main thread ctrl begin: " << std::endl;



while(true) 
{
    sleep(1) ;
  
    // pthread_cond_signal(&cond);  //唤醒在cond的等待队列中等待的一个线程，默认都是第一个

     pthread_cond_broadcast(&cond); //唤醒一批线程
       std::cout << "signal one thread..." << std::endl;
}
    return 0 ;
}